#! /usr/bin/python
import platform, sys

if platform.python_version() < '2.5':
    sys.exit("Python 2.5 is required!")

import getpass
import backend
import hashes
import presets
import clipboard
import command_line
import common
import os
import time

VERSION = "1.05"


def display(settings):
    print "-------------- Settings ----------------------"
    print settings
    print "----------------------------------------------"


def _get_preset_file(preset_filename, password, allow_creation = True):
    import presetfile
    preset_file = presetfile.PresetFile(preset_filename)
    
    if not os.path.exists(preset_filename):
        if not allow_creation:
            raise common.PYMKException("Preset file does not exist!")
        create = raw_input("Preset file does not exist. create? [y/N]").strip().lower() in ("y", "yes")
        if create:
            preset_file.save({}, password)
        else:
            raise common.PYMKException("No preset does not exist!")
    return preset_file

def save_to_preset(settings, preset_name, preset_filename, password, args):
    preset_file = _get_preset_file(preset_filename, password)
    all_presets = preset_file.load(password)
    all_presets[preset_name] = presets.Preset(settings, dict([arg.split("=", 1) for arg in args]))
    preset_file.save(all_presets, password)

def get_preset_settings(preset_name, preset_filename, password):
    preset_file = _get_preset_file(preset_filename, password, allow_creation = False)
    try:
        preset = preset_file.load(password)[preset_name]
    except KeyError:
        raise common.PYMKException("No preset named %r" % options.preset_name)
    if preset.user:
        print "user data"
        print "~~~~~~~~~"
        for key, value in preset.user.iteritems():
            print "%s: %s" % (key, value)
            print
    return preset.settings

def merge_preset_files(dest_filename, dest_password, src_filename, src_password):
    dest = _get_preset_file(dest_filename, dest_password)
    src = _get_preset_file(src_filename, src_password, allow_creation = False)
    dest_presets = dest.load(dest_password)
    src_presets = src.load(src_password)
    dest_presets.update(src_presets)
    dest.save(dest_presets, dest_password)

def list_presets(preset_filename, password):
    presets = _get_preset_file(preset_filename, password, allow_creation = False).load(password)
    print "Available presets:"
    for preset_name in presets.iterkeys():
        print "- %s" % preset_name
        

def main():    
    parser = command_line.get_parser()
    options, args = parser.parse_args()
    
    print "Py_MasterKey Version %s" % VERSION
    
    if options.version_only:
        return
    if options.save and options.preset_name is None:
        raise common.PYMKException("Cannot save without a preset name")
    if (not options.save) and args:
        raise common.PYMKException("Arguments are only valid when saving a preset")
    common.VERBOSE = options.verbose

    
    password = getpass.getpass("Master Password: ").strip()
    if options.list_presets:
        list_presets(options.preset_file, password)
        return
    if options.save or (options.merge is not None):
        password2 = getpass.getpass("Re-enter password: ").strip()
        if password != password2:
            raise common.PYMKException("Passwords don't match!")
    if options.merge is not None:
        other_password = getpass.getpass("Enter password for source preset file: ").strip()
        merge_preset_files(options.preset_file, password, options.merge, other_password)
        return
        
    
    if options.preset_name is not None:
        if options.save:
            settings = common.options2settings(options)
            save_to_preset(settings, options.preset_name, options.preset_file, password, args)
        else:                
            settings = get_preset_settings(options.preset_name, options.preset_file, password)
    else:
        settings = common.options2settings(options)
        
    if common.VERBOSE:
        display(settings)
        
    result = backend.generator.generate(password, settings)
    clipboard.outputPassword(result, not options.no_copy, options.wipe_timeout)
    
    
if __name__ == "__main__":
    try:
        main()
    except common.PYMKException, e:
        print "**** ERROR: %s" % ", ".join(e.args)
    except SystemExit:
        raise
    except Exception, e:
        print "**** UNEXPECTED ERROR: %r:%r" % (e, e.args)
        raise
        time.sleep(5)
    
